package com.jiangxfei.mymvp.di.module;

import android.content.Context;
import android.content.SharedPreferences;

import com.jiangxfei.mymvp.http.net.NetUtils;
import com.jiangxfei.mymvp.http.net.SSLHelper;
import com.jiangxfei.mymvp.util.LogUtil;
import com.jiangxfei.mymvp.util.StringUtil;

import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.concurrent.TimeUnit;

import javax.inject.Named;
import javax.inject.Singleton;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLSession;

import dagger.Module;
import dagger.Provides;
import okhttp3.Cache;
import okhttp3.CacheControl;
import okhttp3.Interceptor;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.logging.HttpLoggingInterceptor;

@Module
public class OkHttpModule {

    private static final int READ_TIMEOUT = 60;//读取超时时间,单位  秒
    private static final int CONN_TIMEOUT = 12;//连接超时时间,单位  秒


    @Singleton
    @Provides
    @Named("default")
     OkHttpClient getOkHttpClient(Context mContext,@Named("default")SharedPreferences sharedPreferences) {
        //cache url :data/data/<package-name>/cache/response
        //参数1：服务器证书文件的InputStream
        //参数2：本地证书文件inputstream
        //参数3：密码
        SSLHelper.SSLParams sslParams = null;
        sslParams = SSLHelper.getSslSocketFactory(null, null, null);
        File httpCacheDirectory = new File(mContext.getCacheDir(), "responses");
        int cacheSize = 10 * 1024 * 1024; // 10 MiB
        Cache cache = new Cache(httpCacheDirectory, cacheSize);
        OkHttpClient.Builder okHttpClient = new OkHttpClient().newBuilder();
        okHttpClient.connectTimeout(CONN_TIMEOUT, TimeUnit.SECONDS);
        okHttpClient.writeTimeout(10, TimeUnit.SECONDS);
        okHttpClient.readTimeout(READ_TIMEOUT, TimeUnit.MINUTES);
        okHttpClient.interceptors().add(getHttpLoggingInterceptor());
        okHttpClient.interceptors().add(getInterceptor(mContext));
        okHttpClient.interceptors().add(setCookie(sharedPreferences));
        okHttpClient.interceptors().add(getCookie(sharedPreferences));
        okHttpClient.hostnameVerifier(
                new HostnameVerifier() {
                    @Override
                    public boolean verify(String hostname, SSLSession session) {
                        return true;
                    }
                }
        );
        okHttpClient.retryOnConnectionFailure(true);
        okHttpClient.sslSocketFactory(sslParams.sSLSocketFactory, sslParams.trustManager);
        return okHttpClient.build();
    }

    /**
     * 设置返回数据的  Interceptor  判断网络   没网读取缓存
     * CacheControl.FORCE_CACHE; //仅仅使用缓存
     * CacheControl.FORCE_NETWORK;// 仅仅使用网络
     *
     * @return
     */
    public Interceptor getInterceptor(Context mContext) {
        return new Interceptor() {
            @Override
            public Response intercept(Chain chain) throws IOException {
                Request request = chain.request();
                if (!NetUtils.isConnected(mContext)) {//无网络
                    request = request.newBuilder()
                            .cacheControl(CacheControl.FORCE_CACHE)
                            .build();

                }
                Response response = chain.proceed(request);
                if (NetUtils.isConnected(mContext)) {
                    int maxAge = 10;// 在线缓存在6s内可读取
                    String cacheControl = request.cacheControl().toString();

                    response.newBuilder()
                            .removeHeader("Pragma")
                            .removeHeader("Cache-Control")
                            .header("Cache-Control", "public, max-age=" + maxAge)
                            .build();
                } else {

                    // 无网络时，设置超时为1周
                    int maxStale = 60 * 60 * 24 * 7;
                    response.newBuilder()
                            .removeHeader("Pragma")
                            .removeHeader("Cache-Control")
                            .header("Cache-Control", "public, only-if-cached, max-stale=" + maxStale)
                            .build();
                }

                return response;
            }
        };
    }

    /**
     * 获取COOKIE
     */
    public Interceptor setCookie(SharedPreferences sp) {
        return new Interceptor() {
            @Override
            public Response intercept(Chain chain) throws IOException {
                // 获取 Cookie
                Response resp = chain.proceed(chain.request());
                List<String> cookies = resp.headers("Set-Cookie");
                String cookieStr = "";
                if (cookies != null && cookies.size() > 0) {
                    for (int i = 0; i < cookies.size(); i++) {
                        cookieStr += cookies.get(i);
                    }
                    SharedPreferences.Editor edit = sp.edit();
                    edit.putString("cookie", cookieStr);
                }
                return resp;
            }
        };
    }

    /**
     * 设置COOKIE
     */
    public Interceptor getCookie(SharedPreferences sp) {
        return new Interceptor() {
            @Override
            public Response intercept(Chain chain) throws IOException {
                // 设置 Cookie
                String cookieStr = sp.getString("cookie", null);
                if (StringUtil.isNotNull(cookieStr)) {
                    return chain.proceed(chain.request().newBuilder().header("Cookie", cookieStr).build());
                }
                return chain.proceed(chain.request());
            }
        };
    }

    /**
     * HttpLog拦截器
     *
     * @return
     */
    private HttpLoggingInterceptor getHttpLoggingInterceptor() {
        HttpLoggingInterceptor httpLoggingInterceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() {

            @Override
            public void log(String message) {
                //打印json日志
                LogUtil.log("----json----", message);
            }
        });
        httpLoggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
        return httpLoggingInterceptor;
    }
}
